package com.example.utils;

import com.alibaba.fastjson2.JSONObject;
import com.example.entity.dto.RuntimeData;
import com.example.entity.vo.request.RuntimeDetailVO;
import com.example.entity.vo.response.RuntimeHistoryVO;
import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.InfluxDBClientFactory;
import com.influxdb.client.WriteApiBlocking;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

@Component
@Slf4j
public class InfluxDbUtils {

    private InfluxDBClient client;

    @PostConstruct //于标记一个方法在 依赖注入完成后 或 Bean 初始化完成后 自动执行
    public void init() {
        String token = "QkLEfhfHd6lcEav0e2hkS-mZCV-PJluVP0oaxUlrraIx4pUagNn15DXUIleWEN19_PeyaydtZ9NDW7iaFp7cMg==";
        client = InfluxDBClientFactory.create("http://127.0.0.1:8086", token.toCharArray());
        log.info("已成功建立连接");
    }

    //写数据
    public void writeRuntimeDate(int clientId, RuntimeDetailVO vo) {
        RuntimeData data = new RuntimeData();
        data.setClientId(clientId);
        data.setDiskWrite(vo.getDiskWrite());
        data.setDiskRead(vo.getDiskRead());
        data.setCpuUsage(vo.getCpuUsage());
        data.setMemoryUsage(vo.getMemoryUsage());
        data.setDiskUsage(vo.getDiskUsage());
        data.setTimestamp(new Date(vo.getTimestamp()).toInstant());
        data.setNetworkDownload(vo.getNetworkDownload());
        data.setNetworkUpload(vo.getNetworkUpload());

        WriteApiBlocking writeApi = client.getWriteApiBlocking();

        writeApi.writeMeasurement("monitor", "or", WritePrecision.NS, data);
    }

    //查找历史数据
    public RuntimeHistoryVO readRuntimeData(int clientId) {
        RuntimeHistoryVO vo = new RuntimeHistoryVO();
        String query = """
                from(bucket: "%s")
                |> range(start: %s)
                |> filter(fn: (r) => r["_measurement"] == "runtime")
                |> filter(fn: (r) => r["clientId"] == "%s")
                """;
        String format = String.format(query, "monitor", "-1h", clientId);
        List<FluxTable> tables = client.getQueryApi().query(format, "or");
        int size = tables.size();
        if (size == 0) return vo;
        List<FluxRecord> records = tables.get(0).getRecords();
        for (int i = 0; i < records.size(); i++) {
            JSONObject object = new JSONObject();
            object.put("timestamp", records.get(i).getTime());
            for (int j = 0; j < size; j++) {
                FluxRecord record = tables.get(j).getRecords().get(i);
                object.put(record.getField(), record.getValue());
            }
            vo.getList().add(object);
        }
        return vo;
    }
}
